package com.daiyang.lottery.service.activitystatus.impl;

import com.daiyang.lottery.common.errorcode.ServiceErrorCodeConstants;
import com.daiyang.lottery.common.exception.ServiceException;
import com.daiyang.lottery.service.ActivityService;
import com.daiyang.lottery.service.activitystatus.ActivityStatusManager;
import com.daiyang.lottery.service.activitystatus.operater.AbstractActivityOperator;
import com.daiyang.lottery.service.dto.ConvertActivityStatusDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@Component
public class ActivityStatusManagerImpL implements ActivityStatusManager {
    private static final Logger logger = LoggerFactory.getLogger(ActivityStatusManager.class);
    @Autowired
    private ActivityService activityService;
    @Autowired
    public final Map<String,AbstractActivityOperator> operatorMap=new HashMap<>();
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handlerEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {


        //1活动状态扭转有依赖性导致代码维护性差
        //2 状态扭转条件可能会扩展，当前写法扩展性差，维护性差
        if(CollectionUtils.isEmpty(operatorMap)){
            logger.warn("operatorMap 为空！");
            return;        //map<String,AbstractActivityOperator>

        }
        Map<String,AbstractActivityOperator> currMap=new HashMap<>(operatorMap);
        Boolean update= false;

        //先处理:人员，奖品
        update=processConvertStatus(convertActivityStatusDTO,currMap,1);
        //后处理：活动
        update=processConvertStatus(convertActivityStatusDTO,currMap,2)||update;
        //更新缓存
        if(update){
            activityService.cacheActivity(convertActivityStatusDTO.getActivityId());
        }



    }

    @Override
    public void rollbackHandlerEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {
        // operatorMap：活动、奖品、人员
        // 活动是否需要回滚？？ 绝对需要，
        // 原因：奖品都恢复成INIT，那么这个活动下的奖品绝对没抽完
        for(AbstractActivityOperator operator:operatorMap.values()){
            operator.convert(convertActivityStatusDTO);
        }

        //更新缓存
        activityService.cacheActivity(convertActivityStatusDTO.getActivityId());
    }

    /**
     * 扭转状态
     * @param convertActivityStatusDTO
     * @param currMap
     * @param
     * @return
     */

    private Boolean processConvertStatus(ConvertActivityStatusDTO convertActivityStatusDTO,
                                         Map<String, AbstractActivityOperator> currMap,
                                         int sequence) {
        //遍历currMap
        Boolean update=false;
        Iterator<Map.Entry<String, AbstractActivityOperator>> iterator
                = currMap.entrySet().iterator();
        while(iterator.hasNext()) {
            AbstractActivityOperator operator = iterator.next().getValue();
            //Operator 是否需要转换
            if(operator.sequence() != sequence||
                    !operator.needConvert(convertActivityStatusDTO)) {
                continue;
            }
            //需要转换：转换
            if(!operator.convert(convertActivityStatusDTO)) {
                logger.warn("状态扭转失败！",operator.getClass().getName());
                throw new ServiceException(ServiceErrorCodeConstants.ACTIVITY_STATUS_CONVERT_ERROR);
            }

            //curMap 删除当前Operator
            iterator.remove();
            update=true;
        }
        //返回
        return update;


    }
}
